#ifndef __THREAD_H__
#define __THREAD_H__

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <ucontext.h>

#include "list.h"

#define STACK_SIZE (1024*1024)



typedef struct 
{
  ucontext_t context; // Le contexte du thread
  int id; // L'id unique du thread
  int isFinished; // Valeur indiquant la terminaison du thread
  int isWaiting; // Valeur indiquant si le thread est attendu par un join
  void* returnValue; // Valeur de retour du thread
} ponyThread;



/*
 * Initialise la librairie
 * - récupère le context de la main 
 * - ?
 *
 */
void thread_init();


/* identifiant de thread
 * NB: pourra être un entier au lieu d'un pointeur si ca vous arrange,
 *     mais attention aux inconvénient des tableaux de threads
 *     (consommation mémoire, cout d'allocation, ...).
 */
typedef void * thread_t;

/* recuperer l'identifiant du thread courant.
 */
extern thread_t thread_self(void);

/* creer un nouveau thread qui va exécuter la fonction func avec l'argument funcarg.
 * renvoie 0 en cas de succès, -1 en cas d'erreur.
 */
extern int thread_create(thread_t *newthread, void *(*func)(void *), void *funcarg);

/* passer la main à un autre thread.
 */
extern int thread_yield(void);

/* attendre la fin d'exécution d'un thread.
 * la valeur renvoyée par le thread est placée dans *retval.
 * si retval est NULL, la valeur de retour est ignorée.
 */
extern int thread_join(thread_t thread, void **retval);

/* terminer le thread courant en renvoyant la valeur de retour retval.
 * cette fonction ne retourne jamais.
 */
extern void thread_exit(void *retval) __attribute__ ((__noreturn__));






void freeEndQueue();
void freePoneyThread(ponyThread* p);
ponyThread* createPonyThread();


#endif /* __THREAD_H__ */
